﻿using CoreDomain.BusinessCore;
using DomainService.IService;
using DomainService.IService.Sys;
using Infrastructure;
using Infrastructure.IRepository.Sys;
using Infrastructure.Repository.Sys;
using Model.BusinessModel.OutPut;
using Model.BusinessModel.OutPut.sys;
using Model.DomainModel.Sys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utility;
using Utility.Enum;

namespace DomainService.Service.Sys
{
    /// <summary>
    /// 部门服务接口实现
    /// </summary>
    public class SysDepartmentService : ISysDepartmentService
    {
        #region 构造实例化

        /// <summary>
        /// 部门底层仓储
        /// </summary>
        private readonly ISysDepartmentRepository _sysDepartmentRepository;

        /// <summary>
        /// 用户底层仓储
        /// </summary>
        private readonly ISysUserRepository _sysUserRepository;

        /// <summary>
        /// 公司底层仓储
        /// </summary>

        private readonly ISysCorporationRepository _sysCorporationRepository;

        /// <summary>
        /// 基础服务
        /// </summary>
        private readonly IBaseService _baseService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sysDepartmentRepository"></param>
        /// <param name="sysUserRepository"></param>
        /// <param name="sysCorporationRepository"></param>
        public SysDepartmentService(ISysDepartmentRepository sysDepartmentRepository, ISysUserRepository sysUserRepository, ISysCorporationRepository sysCorporationRepository, IBaseService baseService)
        {
            _sysDepartmentRepository = sysDepartmentRepository;
            _sysUserRepository = sysUserRepository;
            _sysCorporationRepository = sysCorporationRepository;
            _baseService = baseService;
        }

        #endregion

        #region 业务逻辑

        /// <summary>
        ///  获取公司下的部门
        /// </summary>
        /// <returns></returns>
        public List<TreeOutPut> GetCorporationDepartmentList(string corporationKey)
        {
            var corporationSystemList = _sysDepartmentRepository.GetCorporationDepartmentList(corporationKey);
            var tree = corporationSystemList.ConvertTreeData();
            return tree;
        }

        /// <summary>
        /// 获取所有公司及部门--登录公司为星辰公司，可以获取全部，否则只获取登录公司数据
        /// </summary>
        /// <returns></returns>
        public List<TreeOutPut> GetAllCorporationDepartmentList(string corporationKey)
        {
            var corporationSystemList = _sysDepartmentRepository.GetAllCorporationDepartmentList(corporationKey);
            var tree = corporationSystemList.ConvertTreeData();
            return tree;
        }

        /// <summary>
        /// 新增部门
        /// </summary>
        /// <param name="sysDepartment">部门数据</param>
        public ReceiveStatus Insert(SysDepartment sysDepartment)
        {
            ReceiveStatus receiveStatus = new();
            sysDepartment.Id = Guid.NewGuid().ToString();
            var result = Validate(sysDepartment);
            if (!result.success)
                return result;
            _sysDepartmentRepository.Insert(sysDepartment, BaseSqlRepository.sysDepartment_insertSql);
            return receiveStatus;
        }

        /// <summary>
        /// 修改部门
        /// </summary>
        /// <param name="sysCorporation">部门数据</param>
        public ReceiveStatus Update(SysDepartment sysDepartment)
        {
            ReceiveStatus receiveStatus = new();
            var model = _sysDepartmentRepository.GetByKey(sysDepartment.Id.ToString(), BaseSqlRepository.sysDepartment_selectByKeySql);
            if (model == null)
                return ExceptionHelper.CustomException(string.Format("部门名称【{0}】不存存在或已删除!", sysDepartment.DepartmentName));
            var result = Validate(sysDepartment);
            if (!result.success)
                return result;

            if (sysDepartment.Id.ToLower() == sysDepartment.Pid.ToLower())
            {
                return ExceptionHelper.CustomException("上级部门不能设置当前部门");
            }
            _sysDepartmentRepository.Update(sysDepartment, BaseSqlRepository.sysDepartment_updateSql);
            return receiveStatus;
        }

        /// <summary>
        /// 根据部门ID删除部门
        /// </summary>
        /// <param name="id">部门ID</param>
        /// <returns></returns>
        public ReceiveStatus Delete(string id)
        {
            ReceiveStatus receiveStatus = new();

            //删除前验证
            var model = _sysDepartmentRepository.GetByKey(id, BaseSqlRepository.sysDepartment_selectByKeySql);
            if (model == null)
                return ExceptionHelper.CustomException("当前部门不存在或已删除");

            //获取所有部门id
            var ids = DepartmentCore.GetChildrenDepartmentIdById(id, model.CorporationKey ?? string.Empty);

            //得到要删除部门下的所有人员
            var userList = _sysUserRepository.GetUserByDepId(ids);
            var userId = new List<string?>();
            if (userList != null)
                userId = userList.Select(f => f.UserId).ToList() ?? new List<string?>();

            if (userId.Count > 0)
            {
                string msg = "当前部门存在人员，不能删除!";
                //验证上级部门是否存在或是否是公司
                if (model.Pid == "0" || string.IsNullOrEmpty(model.Pid))
                {
                    return ExceptionHelper.CustomException(msg);
                }
                else
                {
                    var entity = _sysCorporationRepository.GetByKey(model.Pid, BaseSqlRepository.sysCorporation_selectByKeySql);
                    if (entity != null)
                        return ExceptionHelper.CustomException(msg);
                }
            }

            TransactionHelper.ExecuteTransaction(() =>
            {
                //把删除部门下的用户移动到它的上级部门
                _sysUserRepository.SetUserDep(userId, model.Pid.ToString());
                _sysDepartmentRepository.DeleteDepartmentById(ids);
            });
            return receiveStatus;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="sysDepartment"></param>
        /// <returns></returns>
        public ReceiveStatus Validate(SysDepartment sysDepartment)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            /*
            新增/修改前验证
            1、部门的名称不能出现重复
            2、公司不能为空
            */

            if (string.IsNullOrWhiteSpace(sysDepartment.DepartmentName))
                return ExceptionHelper.CustomException("部门名称不能为空!");
            if (string.IsNullOrWhiteSpace(sysDepartment.CorporationKey.ToString()))
                return ExceptionHelper.CustomException("公司不能为空!");

            var sysDepartmentModel = _sysDepartmentRepository.GetSysDepartmentByName(sysDepartment.CorporationKey, sysDepartment.DepartmentName);
            if (sysDepartmentModel != null)
            {
                if (sysDepartment.DepartmentName == sysDepartmentModel.DepartmentName && sysDepartment.Id != sysDepartmentModel.Id)
                    return ExceptionHelper.CustomException(string.Format("部门名称【{0}】已存在,请重新输入", sysDepartment.DepartmentName));
            }

            return receiveStatus;
        }

        /// <summary>
        /// 根据部门ID获取部门人员
        /// </summary>
        /// <param name="id">部门ID</param>
        /// <param name="corporationKey">公司key</param>
        /// <returns></returns>
        public ReceiveStatus<SysDepartmentOutPut> GetDepartmentUserList(string? id, string? corporationKey)
        {
            ReceiveStatus<SysDepartmentOutPut> receiveStatus = new();

            var result = _baseService.GetAuthWhere(RuleTypeEnum.DataRowRule, "su");
            string? authWhere = string.Empty;
            if (result.success) { authWhere = result.data[0]; }
            else
                ExceptionHelper.ThrowBusinessException(result.msg);

            if (!string.IsNullOrWhiteSpace(id))
            {
                var ids = DepartmentCore.GetChildrenDepartmentIdById(id, corporationKey);
                //ids.Add(id);
                receiveStatus.data = _sysDepartmentRepository.GetDepartmentById(ids, corporationKey, authWhere).ToList();
            }
            else
                receiveStatus.data = _sysDepartmentRepository.GetDepartmentById(new List<string>(), corporationKey, authWhere);

            return receiveStatus;
        }

        /// <summary>
        /// 根据公司获取数据
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <returns></returns>
        public ReceiveStatus<SysDepartment> GetAllDepartment(string corporationKey)
        {
            if (string.IsNullOrWhiteSpace(corporationKey))
                return ExceptionHelper<SysDepartment>.CustomExceptionData("请选择公司");
            ReceiveStatus<SysDepartment> receiveStatus = new();
            var list = _sysDepartmentRepository.GetDepartmentByCorporationKey(corporationKey);
            receiveStatus.data = list;
            receiveStatus.msg = "获取成功";
            return receiveStatus;
        }

        #endregion
    }
}
